﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace OptikinetiqControls
{
    /// <summary>
    /// 显示模式
    /// </summary>
    enum DisplayMode
    {
        /// <summary>
        /// 像素级
        /// </summary>
        Pixel,
        /// <summary>
        /// 高质量
        /// </summary>
        HighQuality
    }

    /// <summary>
    /// 操作模式
    /// </summary>
    enum DrawMode
    {
        /// <summary>
        /// 点
        /// </summary>
        Point,
        /// <summary>
        /// 线
        /// </summary>
        Line,
        /// <summary>
        /// 矩形
        /// </summary>
        Rectangle,
        /// <summary>
        /// 旋转矩形
        /// </summary>
        RotateRect,
        /// <summary>
        /// 椭圆
        /// </summary>
        Ellipse,
        /// <summary>
        /// 圆
        /// </summary>
        Circle,
        /// <summary>
        /// 多边形
        /// </summary>
        Polygon,
        /// <summary>
        /// 无操作
        /// </summary>
        None
    }

    enum DrawState
    {
        /// <summary>
        /// 开始
        /// </summary>
        Start,
        /// <summary>
        /// 绘制中
        /// </summary>
        Drawing,
        /// <summary>
        /// 完成
        /// </summary>
        Finish,
        /// <summary>
        /// 移动中
        /// </summary>
        Moving,

        /// <summary>
        /// 绘制线起点拖动
        /// </summary>
        StartDraging,

        /// <summary>
        /// 绘制线终点拖动
        /// </summary>
        EndDraging,

        /// <summary>
        /// 圆形缩放拖动
        /// </summary>
        ScaleDraging,

        /// <summary>
        /// 矩形上边拖动
        /// </summary>
        TopDraging,

        /// <summary>
        /// 矩形下边拖动
        /// </summary>
        BottomDraging,

        /// <summary>
        /// 矩形左边拖动
        /// </summary>
        LeftDraging,

        /// <summary>
        /// 矩形右边拖动
        /// </summary>
        RightDraging,

        /// <summary>
        /// 矩形右下角拖动
        /// </summary>
        BrDraging,

        /// <summary>
        /// 旋转
        /// </summary>
        Rotate,

        Done,

    }

    public partial class HaumDisplayWindow : UserControl
    {
        private Bitmap cloneBmp;

        /// <summary>
        /// 显示图像
        /// </summary>
        public Bitmap imageBmp;

        /// <summary>
        /// 图片文件路径
        /// </summary>
        public string imageFilePath;

        /// <summary>
        /// 缩放比例
        /// </summary>
        private float scaleF = 1.0f;

        /// <summary>
        /// 开始移动时鼠标位置
        /// </summary>
        private Point startMovePosition = Point.Empty;

        /// <summary>
        /// 当前图像基于原图偏移量
        /// </summary>
        private PointF offset = Point.Empty;

        /// <summary>
        /// 图像显示模式 ： 高质量（平滑处理锯齿不失真）， 像素级（能够清晰显示每一个像素，锯齿边缘明显，适合查看像素坐标与rgb值）
        /// </summary>
        private DisplayMode viewMode = DisplayMode.Pixel;

        /// <summary>
        /// 操作模式：记录操作模式或当前绘制图型类型
        /// </summary>
        private DrawMode operatorMode = DrawMode.None;

        /// <summary>
        /// 绘制状态标志位
        /// </summary>
        private DrawState drawState = DrawState.Done;

        /// <summary>
        /// 画笔粗细
        /// </summary>
        private int penSize = 1;

        /// <summary>
        /// 画笔颜色
        /// </summary>
        private Color penColor = Color.Green;

        /// <summary>
        /// 绘制点对象
        /// </summary>
        private DrawPoint drawPoint;
        /// <summary>
        /// 绘制线对象
        /// </summary>
        private DrawLine drawLine;
        /// <summary>
        /// 绘制矩形对象
        /// </summary>
        private DrawRectangle drawRectangle;
        /// <summary>
        /// 绘制椭圆
        /// </summary>
        private DrawEllipse drawEllipse;
        /// <summary>
        /// 绘制圆对象
        /// </summary>
        private DrawCircle drawCircle;
        /// <summary>
        /// 绘制多边形对象
        /// </summary>
        private DrawPolygon drawPolygon;
        /// <summary>
        /// 绘制可旋转矩形
        /// </summary>
        private DrawRotateRect drawRotateRect;
        /// <summary>
        /// 旋转光标
        /// </summary>
        private Cursor rotateCursor;

        /// <summary>
        /// 计时器
        /// </summary>
        private Stopwatch sw = new Stopwatch();

        /// <summary>
        /// 灰度直方器
        /// </summary>
        public IGrayscaleHistogram grayscaleHistogram;

        /// <summary>
        /// 初始化控件
        /// </summary>
        public HaumDisplayWindow()
        {
            InitializeComponent();
            //绑定显示控件鼠标滑动事件 进行缩放
            mainView.MouseWheel += mainView_MouseWheel;
            // 启用控件双缓冲 防止控件重绘闪烁
            this.DoubleBuffered = true;
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.AllPaintingInWmPaint, true);
            //初始化旋转弧形鼠标样式
            // 加载自定义光标文件，这里假设你有一个名为 custom_cursor.cur 的光标文件在项目目录下
            using (MemoryStream ms = new MemoryStream(Properties.Resources.弧线))
            {
                rotateCursor = new Cursor(ms);
            }
        }


        /// <summary>
        /// 显示图片
        /// </summary>
        /// <param name="image">图片</param>
        public void ShowImage(Bitmap image)
        {
            imageBmp = image;
            cloneBmp = image;
            this.Fit();

            int width = image.Width;
            int height = image.Height;

            this.toolStripLabel1.Text = $"{width},{height}";
        }

        /// <summary>
        /// 图像自适应
        /// </summary>
        public void Fit()
        {
            if (imageBmp == null) { return; }
            //计算控件与图像的宽高比例
            float scaleX = (float)(mainView.Width - 2) / imageBmp.Width;
            float scaleY = (float)(mainView.Height - 2) / imageBmp.Height;
            //获取较小的一边比例作为缩放比例
            scaleF = Math.Min(scaleX, scaleY);

            //计算缩放后的图像宽高值
            int newWidth = (int)(imageBmp.Width * scaleF);
            int newHeight = (int)(imageBmp.Height * scaleF);

            //计算图像居中显示的位置
            offset.X = (mainView.Width - newWidth) / 2;
            offset.Y = (mainView.Height - newHeight) / 2;

            //触发自身的Point方法进行控件重绘
            mainView.Invalidate();
        }

        /// <summary>
        /// 导入图片
        /// </summary>
        private void ImportImage()
        {
            //打开文件对话框进行选择图片并触发显示控件重绘
            using (OpenFileDialog ofd = new OpenFileDialog())
            {
                ofd.Filter = "图像文件(*.bmp;*.png;*.jpg;*.jpeg;*.tiff)|*.bmp;*.png;*.jpg;*.jpeg;*.tiff|所有文件(*.*)|*.*";
                ofd.Title = "选择导入并显示图片";
                if (ofd.ShowDialog() == DialogResult.OK)
                {
                    this.ShowImage(new Bitmap(ofd.FileName));
                    imageFilePath = ofd.FileName;
                    this.Fit();
                }
            }
        }

        /// <summary>
        /// 移除图片
        /// </summary>
        private void RemoveImage()
        {
            if (imageBmp == null)
            {
                return;
            }
            imageBmp = null;
            //cloneBmp = null;
            mainView.Invalidate();
        }


        /// <summary>
        /// 保存图片
        /// </summary>
        private bool SaveImage()
        {
            if (imageBmp == null)
            {
                return false;
            }
            //打开保存文件对话框保存图片
            using (SaveFileDialog sfd = new SaveFileDialog())
            {
                sfd.Title = "保存图片到：";
                sfd.DefaultExt = "bmp";
                sfd.CheckPathExists = true;
                sfd.Filter = "BMP|*.bmp|PNG|*.png|JPG|*.jpg|JPEG|*.jpeg|TIFF|*.tiff";
                if (sfd.ShowDialog() == DialogResult.OK)
                {
                    try
                    {
                        string extension = Path.GetExtension(sfd.FileName);
                        switch (extension.ToLower())
                        {
                            case ".bmp":
                                imageBmp.Save(sfd.FileName, ImageFormat.Bmp);
                                break;
                            case ".png":
                                imageBmp.Save(sfd.FileName, ImageFormat.Png);
                                break;
                            case ".jpg":
                            case ".jpeg":
                                imageBmp.Save(sfd.FileName, ImageFormat.Jpeg);
                                break;
                            case ".tiff":
                                imageBmp.Save(sfd.FileName, ImageFormat.Tiff);
                                break;
                            default:

                                break;
                        }
                    }
                    catch (Exception ex) {
                        return false;
                    }
                }
            }
            return true;
        }

        private void ImageSaveByExtension(Image image, string Extension)
        {

        }

        /// <summary>
        /// 保存图片
        /// </summary>
        /// <param name="dir">文件夹路径</param>
        /// <param name="name">文件名（带后缀）</param>
        /// <param name="quality">压缩质量：当文件后缀名为jpg或jpeg时自动启用 取值范围(最差)0-100(最优)</param>
        private void Save(string dir, string name, byte quality = 100)
        {
            string extension = Path.GetExtension(name);

            //如果图像不存在或文件后缀不合理直接返回
            if (imageBmp == null || extension == null || extension == string.Empty)
            {
                return;
            }
            //判断文件夹是否存在，如果不存在先创建文件夹
            Directory.CreateDirectory(dir);
            //组合保存全路径
            string fullPath = Path.Combine(dir, name);
            //将文件后缀名转小写
            extension = extension.Trim().ToLower();
            //判断文件后缀是否需要保存压缩
            if (extension.Equals(".jpg") || extension.Equals(".jpeg"))
            {
                // 获取 JPEG 编码器
                ImageCodecInfo jpegCodecInfo = GetEncoderInfo("image/jpeg");
                // 创建 EncoderParameters 对象，设置压缩质量
                EncoderParameters encoderParameters = new EncoderParameters(1);
                encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
                imageBmp.Save(fullPath, jpegCodecInfo, encoderParameters);
            }
            //不进行压缩
            else
            {
                imageBmp.Save(fullPath);
            }
        }

        /// <summary>
        /// 检索图像编码器与解码器
        /// </summary>
        /// <param name="mimeType">"image/jpeg"</param>
        /// <returns>ImageCodecInfo / None</returns>
        private ImageCodecInfo GetEncoderInfo(string mimeType)
        {
            ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
            for (int i = 0; i < codecs.Length; i++)
            {
                if (codecs[i].MimeType == mimeType)
                {
                    return codecs[i];
                }
            }
            return null;
        }




        /// <summary>
        /// 判断鼠标是否在某一个控件上方
        /// </summary>
        /// <param name="e"></param>
        /// <param name="control"></param>
        /// <returns></returns>
        private bool IsMouseOnCtrl(MouseEventArgs e, Control control)
        {
            int lx = 0;
            int ly = 0;
            int width = control.Width;
            int height = control.Height;

            if (e.X >= lx && e.X < width && e.Y >= ly && e.Y < height)
            {
                return true;
            }
            else
            {
                return false;
            }
        }


        private void mainView_MouseMove(object sender, MouseEventArgs e)
        {
            if (imageBmp == null) { return; }

            //实时计算拖动图片后的鼠标位置并重绘
            if (mainView.Cursor == Cursors.Hand && e.Button == MouseButtons.Left && operatorMode == DrawMode.None)
            {
                Console.WriteLine("拖动图片中...");
                int dx = e.X - startMovePosition.X;
                int dy = e.Y - startMovePosition.Y;
                if (Math.Abs(dx) > 1 || Math.Abs(dy) > 1)
                {
                    offset.X += dx;
                    offset.Y += dy;
                    startMovePosition = e.Location;
                }
            }

            //按住Ctrl键实时计算当前鼠标位置的像素值并显示
            if (Control.ModifierKeys == Keys.Control && IsMouseOnCtrl(e, mainView))
            {

                Console.WriteLine($"正在按住Ctrl...  X:{e.X} Y:{e.Y}");

                //默认提示信息
                string info = $"X:-- Y:-- \n\rR:-- G:-- B--";

                // 计算鼠标在原始图片上的位置
                PointF imagePoint = ScreenTransImagePointF(e.Location);
                // 检查相对位置是否在图片范围内
                if (imagePoint.X >= 0 && imagePoint.X < imageBmp.Width &&
                    imagePoint.Y >= 0 && imagePoint.Y < imageBmp.Height)
                {
                    //获取图像上位置的RGB值
                    Color pixelColor = imageBmp.GetPixel((int)imagePoint.X, (int)imagePoint.Y);
                    //组合提示信息
                    info = $"X:{(int)imagePoint.X} Y:{(int)imagePoint.Y} \n\rR:{pixelColor.R} G:{pixelColor.G} B:{pixelColor.B}";
                }
                //显示提示
                toolTip.Show(info, mainView, e.Location.X + 10, e.Location.Y + 15);
            }
            else
            {
                toolTip.Hide(mainView);
            }

            switch (operatorMode)
            {
                case DrawMode.Point:
                    DrawPoint(e);
                    break;
                case DrawMode.Line:
                    DrawLine(e);
                    break;
                case DrawMode.Rectangle:
                    DrawRectangle(e);
                    break;
                case DrawMode.Circle:
                    DrawCircle(e);
                    break;
                case DrawMode.RotateRect:
                    DrawRotateRect(e);
                    break;
                case DrawMode.Polygon:
                    DrawPolygon(e);
                    break;
            }

            mainView.Invalidate();

        }



        private bool IsMouseOnImage(Point mouseLocation)
        {
            PointF imageLoca = ScreenTransImagePointF(mouseLocation);
            if (imageLoca.X >= 0 && imageLoca.X < imageBmp.Width && imageLoca.Y >= 0 && imageLoca.Y < imageBmp.Height)
            {
                return true;
            }
            else
            {
                return false;
            }
        }


        /// <summary>
        /// 鼠标滚轮滚动事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mainView_MouseWheel(object sender, MouseEventArgs e)
        {
            if (imageBmp != null)
            {
                float zoomFactor = e.Delta > 0 ? 1.1f : 0.9f;
                float oldScale = scaleF;
                scaleF *= zoomFactor;

                // 限制缩放范围
                if (scaleF < 0.01f) scaleF = 0.01f;
                if (scaleF > 100.0f) scaleF = 100.0f;


                // 根据鼠标位置调整偏移量
                float dx = (float)e.X - offset.X;
                float dy = (float)e.Y - offset.Y;
                offset.X -= dx * (scaleF / oldScale - 1);
                offset.Y -= dy * (scaleF / oldScale - 1);


                mainView.Invalidate();
            }
        }


        /// <summary>
        /// 将控件坐标点转为图像坐标点
        /// </summary>
        /// <param name="screenPoint">一个控件坐标点</param>
        /// <returns>图像坐标</returns>
        private PointF ScreenTransImagePointF(Point screenPoint)
        {
            // 计算鼠标在原始图片上的相对位置
            float relativeX = (screenPoint.X - offset.X) / scaleF;
            float relativeY = (screenPoint.Y - offset.Y) / scaleF;

            return new PointF(relativeX, relativeY);
        }

        /// <summary>
        /// 将图像坐标点转为控件坐标点
        /// </summary>
        /// <param name="imagePoint">一个图像坐标点</param>
        /// <returns>控件坐标</returns>
        private Point ImageTransScreenPoint(Point imagePoint)
        {
            float relativeX = imagePoint.X * scaleF + offset.X;
            float relativeY = imagePoint.Y * scaleF + offset.Y;

            return new Point((int)relativeX, (int)relativeY);
        }

        /// <summary>
        /// 将图像坐标点转为控件坐标点
        /// </summary>
        /// <param name="imagePoint">一个图像坐标点</param>
        /// <returns>控件坐标</returns>
        private PointF ImageTransScreenPointF(PointF imagePoint)
        {
            float relativeX = imagePoint.X * scaleF + offset.X;
            float relativeY = imagePoint.Y * scaleF + offset.Y;

            return new PointF(relativeX, relativeY);
        }

        /// <summary>
        /// 将图像坐标点集转为控件坐标点集
        /// </summary>
        /// <param name="imagePoint">一个图像坐标点</param>
        /// <returns>控件坐标</returns>
        private List<PointF> ImageTransScreenPointF(List<PointF> imagePoints)
        {
            List<PointF> ps = new List<PointF>();

            for (int i = 0; i < imagePoints.Count; i++)
            {
                PointF p = ImageTransScreenPointF(imagePoints[i]);
                ps.Add(p);
            }
            return ps;
        }

        private void PaintPoint(PaintEventArgs e)
        {
            using (Pen pen = new Pen(drawPoint.penColor, drawPoint.penSize))
            {
                PointF controlPoint = ImageTransScreenPointF(drawPoint.point);
                float length = 5 * scaleF;
                // 绘制垂直的线（中心点上下各 5 像素）
                e.Graphics.DrawLine(pen, controlPoint.X, controlPoint.Y - length, controlPoint.X, controlPoint.Y + length);
                // 绘制水平的线（中心点左右各 5 像素）
                e.Graphics.DrawLine(pen, controlPoint.X - length, controlPoint.Y, controlPoint.X + length, controlPoint.Y);
            }
        }

        private void PaintLine(PaintEventArgs e)
        {
            using (Pen pen = new Pen(drawLine.penColor, drawLine.penSize))
            {
                using (Pen selectPen = new Pen(drawLine.isSelect ? drawLine.selectColor : drawLine.penColor, drawLine.penSize + 1))
                {
                    //绘制起点中点终点
                    PointF start = ImageTransScreenPointF(drawLine.startPoint);
                    PointF center = ImageTransScreenPointF(drawLine.GetCenter());
                    PointF end = ImageTransScreenPointF(drawLine.endPoint);
                    e.Graphics.DrawEllipse(selectPen, start.X - 1, start.Y - 1, 2, 2);
                    e.Graphics.DrawEllipse(selectPen, center.X - 1, center.Y - 1, 2, 2);
                    e.Graphics.DrawEllipse(selectPen, end.X - 1, end.Y - 1, 2, 2);

                    // 箭头长度
                    float arrowLength = 10 * scaleF;
                    // 箭头角度（V 型开口角度）
                    float arrowAngle = 30;
                    // 箭头朝向角度（相对于水平向右为 0 度）
                    float orientationAngle = drawLine.GetRotate();

                    // 将角度转换为弧度
                    float arrowAngleRadians = arrowAngle * (float)Math.PI / 180;
                    float orientationAngleRadians = orientationAngle * (float)Math.PI / 180;

                    // 尖角点位置
                    PointF tipPoint = center;
                    // 计算 V 型箭头的另外两个点
                    float halfAngle = arrowAngleRadians / 2;
                    PointF point1 = new PointF(
                        tipPoint.X - arrowLength * (float)Math.Cos(orientationAngleRadians - halfAngle),
                        tipPoint.Y - arrowLength * (float)Math.Sin(orientationAngleRadians - halfAngle)
                    );
                    PointF point2 = new PointF(
                        tipPoint.X - arrowLength * (float)Math.Cos(orientationAngleRadians + halfAngle),
                        tipPoint.Y - arrowLength * (float)Math.Sin(orientationAngleRadians + halfAngle)
                    );
                    //绘制尖角两条线形成指向箭头
                    e.Graphics.DrawLine(pen, tipPoint, point1);
                    e.Graphics.DrawLine(pen, tipPoint, point2);
                }
                PointF lineStart = ImageTransScreenPointF(drawLine.startPoint);
                PointF lineEnd = ImageTransScreenPointF(drawLine.endPoint);
                e.Graphics.DrawLine(pen, lineStart, lineEnd);
            }
        }

        private void PaintRectangle(PaintEventArgs e)
        {
            using (Pen pen = new Pen(drawRectangle.penColor, drawRectangle.penSize))
            {
                using (Pen selectPen = new Pen(drawRectangle.isSelect ? drawRectangle.selectColor : drawRectangle.penColor, drawRectangle.penSize + 1))
                {
                    //获取圆心像素坐标 转换成控件坐标
                    PointF center = ImageTransScreenPointF(drawRectangle.GetCenter());
                    //根据中心坐标拟合两条垂直线
                    // 绘制垂直的线（中心点上下各 3 像素）
                    e.Graphics.DrawLine(selectPen, center.X, center.Y - drawRectangle.GetCenterSize() * scaleF, center.X, center.Y + drawRectangle.GetCenterSize() * scaleF);
                    // 绘制水平的线（中心点左右各 3 像素）
                    e.Graphics.DrawLine(selectPen, center.X - drawRectangle.GetCenterSize() * scaleF, center.Y, center.X + drawRectangle.GetCenterSize() * scaleF, center.Y);
                    PointF br = ImageTransScreenPointF(drawRectangle.GetBR());
                    e.Graphics.DrawEllipse(selectPen, br.X - 1, br.Y - 1, 2, 2);
                }
                PointF rectTlLoca = ImageTransScreenPointF(drawRectangle.GetTL());
                PointF rectBrLoca = ImageTransScreenPointF(drawRectangle.GetBR());
                e.Graphics.DrawRectangle(pen, rectTlLoca.X, rectTlLoca.Y, rectBrLoca.X - rectTlLoca.X, rectBrLoca.Y - rectTlLoca.Y);
            }
        }

        private void PaintCircle(PaintEventArgs e)
        {
            using (Pen pen = new Pen(drawCircle.penColor, drawCircle.penSize))
            {
                using (Pen selectPen = new Pen(drawCircle.isSelect ? drawCircle.selectColor : drawCircle.penColor, drawCircle.penSize + 1))
                {
                    //绘制圆心小十字
                    //获取圆心像素坐标 转换成控件坐标
                    PointF center = ImageTransScreenPointF(drawCircle.center);
                    //根据中心坐标拟合两条垂直线
                    // 绘制垂直的线（中心点上下各 3 像素）
                    e.Graphics.DrawLine(selectPen, center.X, center.Y - drawCircle.GetCenterSize() * scaleF, center.X, center.Y + drawCircle.GetCenterSize() * scaleF);
                    // 绘制水平的线（中心点左右各 3 像素）
                    e.Graphics.DrawLine(selectPen, center.X - drawCircle.GetCenterSize() * scaleF, center.Y, center.X + drawCircle.GetCenterSize() * scaleF, center.Y);

                    PointF rightPoint = ImageTransScreenPointF(drawCircle.GetScalePoint());
                    //绘制拖动缩放点
                    e.Graphics.DrawEllipse(selectPen, rightPoint.X - 1, rightPoint.Y - 1, 2, 2);
                }
                //圆的中心坐标转控件坐标
                PointF rectTL = ImageTransScreenPointF(drawCircle.GetRectTL());
                PointF rectBR = ImageTransScreenPointF(drawCircle.GetRectBR());
                SizeF size = new SizeF(rectBR.X - rectTL.X, rectBR.Y - rectTL.Y);
                e.Graphics.DrawEllipse(pen, new RectangleF(rectTL, size));
            }
        }

        private void PaintRotateRect(PaintEventArgs e)
        {
            using (Pen pen = new Pen(drawRotateRect.penColor, drawRotateRect.penSize))
            {
                //绘制矩形
                PointF[] corners = drawRotateRect.GetCorners();
                List<PointF> cornersScr = new List<PointF>();
                for (int i = 0; i < corners.Length; i++)
                {
                    cornersScr.Add(ImageTransScreenPointF(corners[i]));
                }
                e.Graphics.DrawPolygon(pen, cornersScr.ToArray());

                using (Pen selectPen = new Pen(drawRotateRect.isSelect ? drawRotateRect.selectColor : drawRotateRect.penColor, drawRotateRect.penSize + 1))
                {
                    //绘制圆心小十字
                    //获取圆心像素坐标 转换成控件坐标
                    PointF center = ImageTransScreenPointF(drawRotateRect.center);
                    //根据中心坐标拟合两条垂直线
                    // 绘制垂直的线（中心点上下各 3 像素）
                    e.Graphics.DrawLine(selectPen, center.X, center.Y - drawRotateRect.GetCenterSize() * scaleF, center.X, center.Y + drawRotateRect.GetCenterSize() * scaleF);
                    // 绘制水平的线（中心点左右各 3 像素）
                    e.Graphics.DrawLine(selectPen, center.X - drawRotateRect.GetCenterSize() * scaleF, center.Y, center.X + drawRotateRect.GetCenterSize() * scaleF, center.Y);

                    PointF tr = ImageTransScreenPointF(drawRotateRect.tr);
                    e.Graphics.DrawEllipse(selectPen, tr.X - 1, tr.Y - 1, 2, 2);

                    PointF rc = ImageTransScreenPointF(drawRotateRect.GetRightCenter());
                    e.Graphics.DrawEllipse(selectPen, rc.X - 1, rc.Y - 1, 2, 2);

                    PointF bc = ImageTransScreenPointF(drawRotateRect.GetBottomCenter());
                    e.Graphics.DrawEllipse(selectPen, bc.X - 1, bc.Y - 1, 2, 2);
                }
            }
        }

        private void PaintPolygon(PaintEventArgs e)
        {
            using (Pen pen = new Pen(penColor, penSize))
            {
                //绘制路径
                List<PointF> ps = ImageTransScreenPointF(drawPolygon.polygonPath);


                if (drawPolygon.polygonPath.Count >= 2)
                {
                    e.Graphics.DrawLines(pen, ps.ToArray());
                }

                using (Pen selectPen = new Pen(drawPolygon.isSelect ? drawPolygon.selectColor : drawPolygon.penColor, drawPolygon.penSize + 1))
                {
                    //绘制中心小十字
                    //获取圆心像素坐标 转换成控件坐标
                    PointF center = ImageTransScreenPointF(drawPolygon.GetCenter());
                    //根据中心坐标拟合两条垂直线
                    // 绘制垂直的线（中心点上下各 3 像素）
                    e.Graphics.DrawLine(selectPen, center.X, center.Y - drawPolygon.GetCenterSize() * scaleF, center.X, center.Y + drawPolygon.GetCenterSize() * scaleF);
                    // 绘制水平的线（中心点左右各 3 像素）
                    e.Graphics.DrawLine(selectPen, center.X - drawPolygon.GetCenterSize() * scaleF, center.Y, center.X + drawPolygon.GetCenterSize() * scaleF, center.Y);

                    foreach (PointF p in ps)
                    {
                        //绘制拖动缩放点
                        e.Graphics.DrawEllipse(selectPen, p.X - 1, p.Y - 1, 2, 2);
                    }
                }

            }
        }

        /// <summary>
        /// 控件重绘
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mainView_Paint(object sender, PaintEventArgs e)
        {
            sw.Restart();
            if (imageBmp != null)
            {
                // 计算缩放后的图片大小
                int newWidth = (int)(imageBmp.Width * scaleF);
                int newHeight = (int)(imageBmp.Height * scaleF);

                // 判断显示模式设置绘制质量
                if (viewMode == DisplayMode.Pixel)
                {
                    e.Graphics.SmoothingMode = SmoothingMode.None;
                    e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
                    e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
                    e.Graphics.CompositingQuality = CompositingQuality.HighQuality;
                }
                else
                {
                    e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
                    e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
                    e.Graphics.CompositingQuality = CompositingQuality.HighQuality;
                    e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
                }

                // 绘制缩放后的图片
                e.Graphics.DrawImage(imageBmp, offset.X, offset.Y, newWidth, newHeight);

                //更新缩放率
                toolStripSplitButton_scale.Text = $"{(scaleF * 100).ToString("0")}%";

                if (drawPoint != null)
                {
                    PaintPoint(e);
                }

                if (drawLine != null)
                {
                    PaintLine(e);
                }

                if (drawCircle != null)
                {
                    PaintCircle(e);
                }

                if (drawEllipse != null)
                {

                }

                if (drawRectangle != null)
                {
                    PaintRectangle(e);
                }

                if (drawRotateRect != null)
                {
                    PaintRotateRect(e);
                }

                if (drawPolygon != null && drawPolygon.polygonPath.Count > 0)
                {
                    PaintPolygon(e);
                }
            }
            sw.Stop();
            if (sw.ElapsedMilliseconds > 0)
            {
                Console.WriteLine("重绘耗时ms：" + sw.ElapsedMilliseconds + " fps:" + 1000 / sw.ElapsedMilliseconds);
            }
        }


        private void mainView_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left && mainView.Cursor == Cursors.Hand)
            {
                startMovePosition = e.Location;
            }

            if (e.Button == MouseButtons.Right && operatorMode == DrawMode.None && drawState == DrawState.Done)
            {
                contextMenuStrip_menu.Show(mainView, e.Location);
                Point testPoint = ImageTransScreenPoint(new Point(0, 0));
                Console.WriteLine($" Sx:{testPoint.X} Sy:{testPoint.Y}");
            }

            switch (operatorMode)
            {
                case DrawMode.Point:
                    DrawPoint(e);
                    break;
                case DrawMode.Line:
                    DrawLine(e);
                    break;
                case DrawMode.Rectangle:
                    DrawRectangle(e);
                    break;
                case DrawMode.RotateRect:
                    DrawRotateRect(e);
                    break;
                case DrawMode.Circle:
                    DrawCircle(e);
                    break;
                case DrawMode.Polygon:
                    DrawPolygon(e);
                    break;
            }

            mainView.Invalidate();

        }


        private bool IsCanSelect(PointF center, Point mouse, float relative)
        {

            PointF screenCenter = ImageTransScreenPointF(center);

            if (Math.Abs(mouse.X - screenCenter.X) <= relative && Math.Abs(mouse.Y - screenCenter.Y) <= relative)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        private void contextMenuStrip_menu_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            this.contextMenuStrip_menu.Close();

            string clickedItemText = e.ClickedItem.Text;
            Console.WriteLine(clickedItemText);

            switch (clickedItemText)
            {
                case "导入图像":
                    this.ImportImage();
                    break;
                case "自适应":
                    this.Fit();
                    break;
                case "水平翻转":
                    this.FlipX();
                    break;
                case "垂直翻转":
                    this.FlipY();
                    break;
                case "顺时针旋转":
                    this.RightRotate();
                    break;
                case "逆时针旋转":
                    this.LeftRotate();
                    break;
                case "恢复":
                    this.Restore();
                    break;
                case "像素级":
                    viewMode = DisplayMode.Pixel;
                    mainView.Invalidate();
                    break;
                case "高质量":
                    viewMode = DisplayMode.HighQuality;
                    mainView.Invalidate();
                    break;
                case "Point":
                    Console.WriteLine("画一个点");
                    StartDrawPoint();
                    break;
                case "Line":
                    Console.WriteLine("画一条线");
                    StartDrawLine();
                    break;
                case "Rectangle":
                    Console.WriteLine("画一个矩形");
                    StartDrawRectangle();
                    break;
                case "RotateRect":
                    Console.WriteLine("画一个旋转矩形");
                    StartDrawRotateRect();
                    break;
                case "Circle":
                    Console.WriteLine("画一个圆形");
                    StartDrawCircle();
                    break;
                case "Eclipse":
                    Console.WriteLine("画一个椭圆");
                    break;
                case "Polygon":
                    Console.WriteLine("画多边形");
                    StartDrawPolygon();
                    break;
                case "1":
                    Console.WriteLine("设置宽度1");
                    penSize = 1;
                    break;
                case "2":
                    Console.WriteLine("设置宽度2");
                    penSize = 2;
                    break;
                case "3":
                    Console.WriteLine("设置宽度3");
                    penSize = 3;
                    break;
                case "4":
                    Console.WriteLine("设置宽度4");
                    penSize = 4;
                    break;
                case "5":
                    Console.WriteLine("设置宽度5");
                    penSize = 5;
                    break;
                case "Black":
                    Console.WriteLine("设置黑色");
                    penColor = Color.Black;
                    break;
                case "White":
                    Console.WriteLine("设置白色");
                    penColor = Color.White;
                    break;
                case "Red":
                    Console.WriteLine("设置红色");
                    penColor = Color.Red;
                    break;
                case "Green":
                    Console.WriteLine("设置绿色");
                    penColor = Color.Green;
                    break;
                case "Blue":
                    Console.WriteLine("设置蓝色");
                    penColor = Color.Blue;
                    break;
                case "Yellow":
                    Console.WriteLine("设置黄色");
                    penColor = Color.Yellow;
                    break;
                case "移除图像":
                    Console.WriteLine("移除图像");
                    this.RemoveImage();
                    break;
                case "保存图像":
                    Console.WriteLine("保存图像");
                    this.SaveImage();
                    break;

                default:

                    break;
            }
        }

        private void mainView_Resize(object sender, EventArgs e)
        {
            if (imageBmp != null)
            {
                // 计算初始的缩放比例和偏移量

            }
        }


        #region 操作封装



        private void ClearDraw()
        {
            if (operatorMode == DrawMode.None && drawState == DrawState.Done)
            {
                drawPoint = null;
                drawLine = null;
                drawRectangle = null;
                drawRotateRect = null;
                drawCircle = null;
                drawPolygon = null;
                mainView.Invalidate();
            }
        }

        private void StartDrawPoint()
        {
            if (imageBmp != null)
            {
                drawPoint = new DrawPoint();
                drawPoint.penColor = penColor;
                drawPoint.penSize = penSize;
                operatorMode = DrawMode.Point;
                drawState = DrawState.Start;
                mainView.Cursor = Cursors.Cross;
            }
        }

        private void DrawPoint(MouseEventArgs e)
        {
            switch (drawState)
            {
                case DrawState.Start:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        drawPoint.point = ScreenTransImagePointF(e.Location);
                        drawState = DrawState.Drawing;
                    }
                    break;
                case DrawState.Drawing:
                    //更新点的位置
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        drawPoint.point = ScreenTransImagePointF(e.Location);
                    }
                    break;
            }
        }

        private void StartDrawLine()
        {
            if (imageBmp != null)
            {
                drawLine = new DrawLine();
                drawLine.penColor = penColor;
                drawLine.penSize = penSize;
                operatorMode = DrawMode.Line;
                drawState = DrawState.Start;
                mainView.Cursor = Cursors.Cross;
            }
        }

        private void DrawLine(MouseEventArgs e)
        {
            switch (drawState)
            {

                case DrawState.Start:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        drawLine.startPoint = ScreenTransImagePointF(e.Location);
                        drawLine.endPoint = ScreenTransImagePointF(e.Location);
                        drawState = DrawState.Drawing;
                    }
                    break;
                case DrawState.Drawing:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        drawLine.endPoint = ScreenTransImagePointF(e.Location);
                    }
                    else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        drawState = DrawState.Finish;
                    }
                    break;
                case DrawState.Finish:
                    if (IsMouseOnImage(e.Location) && IsCanSelect(drawLine.GetCenter(), e.Location, 5) ||
                        IsCanSelect(drawLine.startPoint, e.Location, 5) || IsCanSelect(drawLine.endPoint, e.Location, 5))
                    {
                        mainView.Cursor = Cursors.SizeAll;
                        drawLine.isSelect = true;
                    }
                    else
                    {
                        mainView.Cursor = Cursors.Cross;
                        drawLine.isSelect = false;
                    }

                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && IsCanSelect(drawLine.GetCenter(), e.Location, 5))
                    {
                        drawState = DrawState.Moving;
                    }
                    else if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && IsCanSelect(drawLine.startPoint, e.Location, 5))
                    {
                        drawState = DrawState.StartDraging;
                    }
                    else if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && IsCanSelect(drawLine.endPoint, e.Location, 5))
                    {
                        drawState = DrawState.EndDraging;
                    }
                    else if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && !IsCanSelect(drawLine.GetCenter(), e.Location, 5))
                    {
                        drawState = DrawState.Start;
                    }
                    break;
                case DrawState.Moving:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        float relativeX = ScreenTransImagePointF(e.Location).X - drawLine.GetCenter().X;
                        float relativeY = ScreenTransImagePointF(e.Location).Y - drawLine.GetCenter().Y;
                        //更新坐标
                        drawLine.startPoint.X += relativeX;
                        drawLine.startPoint.Y += relativeY;

                        drawLine.endPoint.X += relativeX;
                        drawLine.endPoint.Y += relativeY;
                    }
                    else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        drawState = DrawState.Finish;
                    }
                    break;
                case DrawState.StartDraging:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        //更新起点坐标
                        drawLine.startPoint = ScreenTransImagePointF(e.Location);
                    }
                    else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        drawState = DrawState.Finish;
                    }
                    break;
                case DrawState.EndDraging:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        //更新终点坐标
                        drawLine.endPoint = ScreenTransImagePointF(e.Location);
                    }
                    else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        drawState = DrawState.Finish;
                    }
                    break;
            }
        }

        private void StartDrawRectangle()
        {
            if (imageBmp != null)
            {
                drawRectangle = new DrawRectangle();
                drawRectangle.penColor = penColor;
                drawRectangle.penSize = penSize;
                operatorMode = DrawMode.Rectangle;
                drawState = DrawState.Start;
                mainView.Cursor = Cursors.Cross;
            }
        }

        private void DrawRectangle(MouseEventArgs e)
        {
            switch (drawState)
            {
                case DrawState.Start:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        drawRectangle.rect.Location = ScreenTransImagePointF(e.Location);
                        drawState = DrawState.Drawing;
                    }
                    break;
                case DrawState.Drawing:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        PointF rbLoca = ScreenTransImagePointF(e.Location);
                        drawRectangle.rect.Width = Math.Abs(rbLoca.X - drawRectangle.rect.X);
                        drawRectangle.rect.Height = Math.Abs(rbLoca.Y - drawRectangle.rect.Y);
                    }
                    else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        drawState = DrawState.Finish;
                    }
                    break;
                case DrawState.Finish:
                    //显示
                    if (IsMouseOnImage(e.Location) && IsCanSelect(drawRectangle.GetCenter(), e.Location, 5))
                    {
                        mainView.Cursor = Cursors.SizeAll;
                        drawRectangle.isSelect = true;
                    }
                    else if (IsMouseOnImage(e.Location) && IsCanSelect(drawRectangle.GetBR(), e.Location, 5))
                    {
                        mainView.Cursor = Cursors.SizeNWSE;
                        drawRectangle.isSelect = true;
                    }
                    else
                    {
                        mainView.Cursor = Cursors.Cross;
                        drawRectangle.isSelect = false;
                    }

                    //操作
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && IsCanSelect(drawRectangle.GetCenter(), e.Location, 5))
                    {
                        drawState = DrawState.Moving;
                    }
                    else if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && IsCanSelect(drawRectangle.GetBR(), e.Location, 5))
                    {
                        drawState = DrawState.BrDraging;
                    }
                    else if (e.Button == MouseButtons.Left && !IsCanSelect(drawRectangle.GetCenter(), e.Location, 5) && !IsCanSelect(drawRectangle.GetBR(), e.Location, 5))
                    {
                        drawState = DrawState.Start;
                    }
                    break;
                case DrawState.Moving:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        //更新坐标
                        drawRectangle.rect.X = ScreenTransImagePointF(e.Location).X - drawRectangle.rect.Width / 2;
                        drawRectangle.rect.Y = ScreenTransImagePointF(e.Location).Y - drawRectangle.rect.Height / 2;
                    }
                    else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        drawState = DrawState.Finish;
                    }
                    break;

                case DrawState.BrDraging:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        //更新宽高
                        PointF mouse = ScreenTransImagePointF(e.Location);
                        drawRectangle.rect.Width = Math.Abs(mouse.X - drawRectangle.rect.X);
                        drawRectangle.rect.Height = Math.Abs(mouse.Y - drawRectangle.rect.Y);
                    }
                    else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        drawState = DrawState.Finish;
                    }
                    break;
            }
        }

        private void StartDrawEllipse()
        {
            if (imageBmp != null)
            {
                drawEllipse = new DrawEllipse();
                drawEllipse.penColor = penColor;
                drawEllipse.penSize = penSize;
                operatorMode = DrawMode.Ellipse;
                drawState = DrawState.Start;
                mainView.Cursor = Cursors.Cross;
            }
        }

        private void DrawEllipse(MouseEventArgs e)
        {
            switch (drawState)
            {
                case DrawState.Start:

                    break;
                case DrawState.Drawing:

                    break;
                case DrawState.Finish:

                    break;
                case DrawState.Moving:

                    break;
            }
        }

        /// <summary>
        /// 开始绘制圆
        /// </summary>
        private void StartDrawCircle()
        {
            if (imageBmp != null)
            {
                drawCircle = new DrawCircle();
                drawCircle.penColor = penColor;
                drawCircle.penSize = penSize;
                operatorMode = DrawMode.Circle;
                drawState = DrawState.Start;
                mainView.Cursor = Cursors.Cross;
            }
        }

        private void DrawCircle(MouseEventArgs e)
        {
            switch (drawState)
            {

                case DrawState.Start:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        drawCircle.center = ScreenTransImagePointF(e.Location);
                        drawState = DrawState.Drawing;
                    }
                    break;
                case DrawState.Drawing:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        PointF movePoint = ScreenTransImagePointF(e.Location);
                        //计算圆半径
                        drawCircle.radius = (float)Math.Sqrt(Math.Pow(Math.Abs(movePoint.X - drawCircle.center.X), 2) + Math.Pow(Math.Abs(movePoint.Y - drawCircle.center.Y), 2));
                    }
                    else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        drawState = DrawState.Finish;
                    }
                    break;
                case DrawState.Finish:
                    if (IsMouseOnImage(e.Location) && IsCanSelect(drawCircle.center, e.Location, 5))
                    {
                        mainView.Cursor = Cursors.SizeAll;
                        drawCircle.isSelect = true;
                    }
                    else if (IsMouseOnImage(e.Location) && IsCanSelect(drawCircle.GetScalePoint(), e.Location, 5))
                    {
                        mainView.Cursor = Cursors.SizeWE;
                        drawCircle.isSelect = true;
                    }
                    else
                    {
                        mainView.Cursor = Cursors.Cross;
                        drawCircle.isSelect = false;
                    }

                    //更新
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && IsCanSelect(drawCircle.center, e.Location, 5))
                    {
                        drawState = DrawState.Moving;
                    }
                    else if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && IsCanSelect(drawCircle.GetScalePoint(), e.Location, 5))
                    {
                        drawState = DrawState.ScaleDraging;
                    }
                    else if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && !IsCanSelect(drawCircle.center, e.Location, 5))
                    {
                        drawState = DrawState.Start;
                    }
                    break;
                case DrawState.Moving:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        //更新坐标
                        drawCircle.center = ScreenTransImagePointF(e.Location);
                    }
                    else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        drawState = DrawState.Finish;
                    }
                    break;
                case DrawState.ScaleDraging:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        //更新半径
                        drawCircle.radius = ScreenTransImagePointF(e.Location).X - drawCircle.center.X;
                    }
                    else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        drawState = DrawState.Finish;
                    }
                    break;
            }
        }

        private void StartDrawRotateRect()
        {
            if (imageBmp != null)
            {
                drawRotateRect = new DrawRotateRect();
                drawRotateRect.penColor = penColor;
                drawRotateRect.penSize = penSize;
                operatorMode = DrawMode.RotateRect;
                drawState = DrawState.Start;
                mainView.Cursor = Cursors.Cross;
            }
        }

        private void DrawRotateRect(MouseEventArgs e)
        {
            switch (drawState)
            {
                case DrawState.Start:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        drawRotateRect.center = ScreenTransImagePointF(e.Location);
                        drawState = DrawState.Drawing;
                    }
                    break;
                case DrawState.Drawing:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        float w = ScreenTransImagePointF(e.Location).X - drawRotateRect.center.X;
                        float h = ScreenTransImagePointF(e.Location).Y - drawRotateRect.center.Y;
                        drawRotateRect.widthHalf = w;
                        drawRotateRect.heightHalf = h;
                    }
                    else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        drawState = DrawState.Finish;
                    }
                    break;
                case DrawState.Finish:
                    //显示
                    if (IsMouseOnImage(e.Location) && IsCanSelect(drawRotateRect.center, e.Location, 5))
                    {
                        mainView.Cursor = Cursors.SizeAll;
                        drawRotateRect.isSelect = true;
                    }
                    else if (IsMouseOnImage(e.Location) && IsCanSelect(drawRotateRect.tr, e.Location, 10))
                    {
                        mainView.Cursor = rotateCursor;
                        drawRotateRect.isSelect = true;
                    }
                    else if (IsMouseOnImage(e.Location) && IsCanSelect(drawRotateRect.GetRightCenter(), e.Location, 5))
                    {
                        mainView.Cursor = Cursors.SizeWE;
                        drawRotateRect.isSelect = true;
                    }
                    else if (IsMouseOnImage(e.Location) && IsCanSelect(drawRotateRect.GetBottomCenter(), e.Location, 5))
                    {
                        mainView.Cursor = Cursors.SizeNS;
                        drawRotateRect.isSelect = true;
                    }
                    else
                    {
                        mainView.Cursor = Cursors.Cross;
                        drawRotateRect.isSelect = false;
                    }

                    //操作
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && IsCanSelect(drawRotateRect.center, e.Location, 5))
                    {
                        drawState = DrawState.Moving;
                    }
                    else if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && IsCanSelect(drawRotateRect.tr, e.Location, 10))
                    {
                        drawState = DrawState.Rotate;
                    }
                    else if (e.Button == MouseButtons.Left && IsCanSelect(drawRotateRect.GetRightCenter(), e.Location, 5))
                    {
                        drawState = DrawState.RightDraging;
                    }
                    else if (e.Button == MouseButtons.Left && IsCanSelect(drawRotateRect.GetBottomCenter(), e.Location, 5))
                    {
                        drawState = DrawState.BottomDraging;
                    }
                    else if (e.Button == MouseButtons.Left && !IsCanSelect(drawRotateRect.center, e.Location, 5) && !IsCanSelect(drawRotateRect.tr, e.Location, 5))
                    {
                        drawState = DrawState.Start;
                    }
                    break;
                case DrawState.Moving:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        //更新坐标
                        PointF newP = ScreenTransImagePointF(e.Location);
                        drawRotateRect.MoveCenrer(newP);
                    }
                    else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        drawState = DrawState.Finish;
                    }
                    break;
                case DrawState.Rotate:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        //计算角度
                        PointF mouse = ScreenTransImagePointF(e.Location);
                        //计算中心与右上角角度
                        double r = ShapeTools.GetRotate(drawRotateRect.center, drawRotateRect.tr);
                        //计算鼠标与中心的角度
                        double mr = ShapeTools.GetRotate(drawRotateRect.center, mouse);
                        //角点旋转
                        drawRotateRect.Rotate(mr - r);

                        //获取左边与右边中点 计算矩形当前角度
                        drawRotateRect.rotate = ShapeTools.GetRotate(drawRotateRect.GetLeftCenter(), drawRotateRect.GetRightCenter());
                        if (Math.Abs(drawRotateRect.rotate) > 0 && Math.Abs(drawRotateRect.rotate) < 1)
                        {
                            drawRotateRect.Rotate(0 - drawRotateRect.rotate);
                            drawRotateRect.rotate += 0 - drawRotateRect.rotate;
                        }

                        Console.WriteLine(drawRotateRect.rotate);
                    }
                    else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        drawState = DrawState.Finish;
                    }
                    break;
                case DrawState.RightDraging:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        float w = ScreenTransImagePointF(e.Location).X - drawRotateRect.center.X;
                        drawRotateRect.widthHalf = w;
                    }
                    else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        drawState = DrawState.Finish;
                    }
                    break;
                case DrawState.BottomDraging:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        float h = ScreenTransImagePointF(e.Location).Y - drawRotateRect.center.Y;
                        drawRotateRect.heightHalf = h;
                    }
                    else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        drawState = DrawState.Finish;
                    }
                    break;
            }
        }


        /// <summary>
        /// 开始绘制多边形
        /// </summary>
        private void StartDrawPolygon()
        {
            if (imageBmp != null)
            {
                drawPolygon = new DrawPolygon();
                drawPolygon.penColor = penColor;
                drawPolygon.penSize = penSize;
                operatorMode = DrawMode.Polygon;
                drawState = DrawState.Start;
                mainView.Cursor = Cursors.Cross;
            }
        }

        /// <summary>
        /// 绘制多边形
        /// </summary>
        /// <param name="e"></param>
        private void DrawPolygon(MouseEventArgs e)
        {
            switch (drawState)
            {
                case DrawState.Start:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        if (drawPolygon.polygonPath.Count > 1)
                        {
                            drawPolygon.polygonPath.Clear();
                        }
                        //添加起点
                        drawPolygon.polygonPath.Add(ScreenTransImagePointF(e.Location));
                        drawState = DrawState.Drawing;
                    }
                    break;
                case DrawState.Drawing:
                    if (IsMouseOnImage(e.Location) && IsCanSelect(drawPolygon.polygonPath[0], e.Location, 5))
                    {
                        mainView.Cursor = Cursors.Hand;
                    }
                    else
                    {
                        mainView.Cursor = Cursors.Cross;
                    }

                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && !IsCanSelect(drawPolygon.polygonPath[0], e.Location, 5))
                    {
                        //添加路径
                        drawPolygon.polygonPath.Add(ScreenTransImagePointF(e.Location));
                    }
                    else if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && IsCanSelect(drawPolygon.GetCenter(), e.Location, 5))
                    {
                        drawState = DrawState.Moving;
                    }
                    else if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && IsCanSelect(drawPolygon.polygonPath[0], e.Location, 5))
                    {
                        PointF start = drawPolygon.polygonPath[0];
                        drawPolygon.polygonPath.Add(start);
                        drawState = DrawState.Finish;
                    }
                    break;
                case DrawState.Finish:
                    if (IsMouseOnImage(e.Location) && IsCanSelect(drawPolygon.GetCenter(), e.Location, 5))
                    {
                        mainView.Cursor = Cursors.SizeAll;
                        drawPolygon.isSelect = true;
                    }
                    else
                    {
                        mainView.Cursor = Cursors.Cross;
                        drawPolygon.isSelect = false;
                    }

                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && IsCanSelect(drawPolygon.GetCenter(), e.Location, 5))
                    {
                        drawState = DrawState.Moving;
                    }
                    else if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && !IsCanSelect(drawPolygon.polygonPath[0], e.Location, 5))
                    {
                        drawState = DrawState.Start;
                    }
                    break;
                case DrawState.Moving:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        //更新坐标
                        drawPolygon.ChangeAllPath(ScreenTransImagePointF(e.Location));
                    }
                    else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        drawState = DrawState.Finish;
                    }
                    break;
            }
        }


        /// <summary>
        /// 结束绘制
        /// </summary>
        private void DrawEnd()
        {
            operatorMode = DrawMode.None;
            drawState = DrawState.Done;
            mainView.Cursor = Cursors.Default;
        }

        private void FlipX()
        {
            if (imageBmp != null)
            {
                imageBmp.RotateFlip(RotateFlipType.RotateNoneFlipX);
                this.Fit();
            }
        }

        private void FlipY()
        {
            if (imageBmp != null)
            {
                imageBmp.RotateFlip(RotateFlipType.RotateNoneFlipY);
                this.Fit();
            }
        }

        private void LeftRotate()
        {
            if (imageBmp != null)
            {
                imageBmp.RotateFlip(RotateFlipType.Rotate270FlipNone);
                this.Fit();
            }
        }

        private void RightRotate()
        {
            if (imageBmp != null)
            {
                imageBmp.RotateFlip(RotateFlipType.Rotate90FlipNone);
                this.Fit();
            }
        }

        private void Restore()
        {
            if (cloneBmp != null)
            {
                imageBmp = cloneBmp.Clone() as Bitmap;
                this.Fit();
            }
        }


        #endregion

        private void toolStripButton_clear_Click(object sender, EventArgs e)
        {
            this.ClearDraw();
        }

        /// <summary>
        /// 鼠标样式切换到箭头
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        private void toolStripButton_arrow_Click(object sender, EventArgs e)
        {
            if (operatorMode == DrawMode.None)
            {
                mainView.Cursor = Cursors.Arrow;
            }
        }

        /// <summary>
        /// 鼠标样式切换到抓手
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        private void toolStripButton_hand_Click(object sender, EventArgs e)
        {
            if (operatorMode == DrawMode.None)
            {
                mainView.Cursor = Cursors.Hand;
            }
        }

        /// <summary>
        /// 自适应显示
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripButton_fit_Click(object sender, EventArgs e)
        {
            this.Fit();
        }

        /// <summary>
        /// 缩放选项点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripSplitButton_scale_DropDownItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            if (imageBmp == null) { return; }

            float oldScale = scaleF;

            switch (e.ClickedItem.Text)
            {
                case "50%":
                    scaleF = 0.5f;
                    break;
                case "100%":
                    scaleF = 1f;
                    break;
                case "150%":
                    scaleF = 1.5f;
                    break;
                case "200%":
                    scaleF = 2f;
                    break;
            }

            float dx = mainView.Width / 2 - offset.X;
            float dy = mainView.Height / 2 - offset.Y;
            offset.X -= dx * (scaleF / oldScale - 1);
            offset.Y -= dy * (scaleF / oldScale - 1);

            mainView.Invalidate();
        }


        private void toolStripButton_leftRotate_Click(object sender, EventArgs e)
        {
            LeftRotate();
        }

        private void toolStripButton_rightRotate_Click(object sender, EventArgs e)
        {
            RightRotate();
        }

        private void toolStripMenuItem_point_Click(object sender, EventArgs e)
        {
            StartDrawPoint();
        }

        private void toolStripMenuItem_line_Click(object sender, EventArgs e)
        {
            StartDrawLine();
        }

        private void toolStripMenuItem_rectangle_Click(object sender, EventArgs e)
        {
            StartDrawRectangle();
        }

        private void toolStripMenuItem_circle_Click(object sender, EventArgs e)
        {
            StartDrawCircle();
        }

        private void mainView_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right && drawState != DrawState.Done)
            {
                switch (operatorMode)
                {
                    case DrawMode.Point:
                        drawPoint.isSelect = false;
                        Console.WriteLine($"Point X:{(int)drawPoint.point.X} Y:{(int)drawPoint.point.Y}");
                        break;
                    case DrawMode.Line:
                        drawLine.isSelect = false;
                        Console.WriteLine($"Line sX:{drawLine.startPoint.X} sY:{drawLine.startPoint.Y} --- eX:{drawLine.endPoint.X} eY:{drawLine.endPoint.Y}");
                        break;
                    case DrawMode.Circle:
                        drawCircle.isSelect = false;
                        // 计算在图片上的位置
                        Console.WriteLine($"Circle X:{drawCircle.center.X} Y:{drawCircle.center.Y} --- R:{drawCircle.radius}");
                        break;
                    case DrawMode.Rectangle:
                        drawRectangle.isSelect = false;
                        Console.WriteLine($"Rectangle X:{drawRectangle.rect.X} Y:{drawRectangle.rect.Y} --- width:{drawRectangle.GetSize().Width} height:{drawRectangle.GetSize().Height}");
                        break;
                    case DrawMode.RotateRect:
                        drawRotateRect.isSelect = false;
                        Console.WriteLine($"RotateRect cX:{drawRotateRect.center.X} cY:{drawRotateRect.center.Y} --- width:{drawRotateRect.widthHalf} height:{drawRotateRect.heightHalf}  rotate:{drawRotateRect.rotate}");
                        break;
                    case DrawMode.Polygon:
                        drawPolygon.isSelect = false;
                        break;
                }
                this.DrawEnd();

            }
        }

        private void toolStripMenuItem_polygon_Click(object sender, EventArgs e)
        {
            StartDrawPolygon();
        }

        private void toolStripMenuItem_rotateRect_Click(object sender, EventArgs e)
        {
            StartDrawRotateRect();
        }

        public DrawPoint GetDrawPoint()
        {
            return drawPoint;
        }

        public DrawLine GetDrawLine()
        {
            return drawLine;
        }

        public DrawCircle GetDrawCircle()
        {
            return drawCircle;
        }

        public DrawRectangle GetDrawRectangle()
        {
            return drawRectangle;
        }

        public DrawRotateRect GetRotateRect()
        {
            return drawRotateRect;
        }

        public DrawPolygon GetDrawPolygon()
        {
            return drawPolygon;
        }

        private void mainView_SizeChanged(object sender, EventArgs e)
        {
            this.Fit();
        }

    }
}
